package com.coisini.service.impl;

import com.coisini.constant.MessageConstant;
import com.coisini.constant.StatusConstant;
import com.coisini.dto.DishDTO;
import com.coisini.dto.DishPageQueryDTO;
import com.coisini.entity.Dish;
import com.coisini.entity.DishFlavor;
import com.coisini.entity.Setmeal;
import com.coisini.exception.DeletionNotAllowedException;
import com.coisini.mapper.DishFlavorMapper;
import com.coisini.mapper.DishMapper;
import com.coisini.mapper.SetmealDishMapper;
import com.coisini.mapper.SetmealMapper;
import com.coisini.result.PageResult;
import com.coisini.service.DishService;
import com.coisini.vo.DishVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;

/**
 * 菜品业务
 */
@Service
public class DishServiceImpl implements DishService {

    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private DishFlavorMapper dishFlavorMapper;
    @Autowired
    private SetmealDishMapper setmealDishMapper;
    @Autowired
    private SetmealMapper setmealMapper;

    /**
     * 菜品分页查询
     * @param dishPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(DishPageQueryDTO dishPageQueryDTO) {
        //设置分页查询条件
        PageHelper.startPage(dishPageQueryDTO.getPage(),dishPageQueryDTO.getPageSize());
        //调用mapper接口
        List<DishVO> dishList = dishMapper.pageQuery(dishPageQueryDTO);
        Page<DishVO> dishPage= (Page<DishVO>) dishList;
        return new PageResult(dishPage.getTotal(),dishPage.getResult());
    }

    /**
     * 新增菜品及口味
     * 菜品跟口味，一起添加或者一起失败
     * @param dishDTO
     */
    @Transactional
    @Override
    public void saveWithFlavor(DishDTO dishDTO) {
        //拷贝属性
        Dish dish=new Dish();
        BeanUtils.copyProperties(dishDTO,dish);
        //调用mapper接口完成新增菜品的sql语句
        dishMapper.insert(dish);
        //执行完sql语句后，需要拿到该菜品的id值
        Long id = dish.getId();

        //新增口味
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors != null  && flavors.size() > 0){
            //遍历这个集合，将id值赋值进去
//            flavors.forEach(new Consumer<DishFlavor>() {
//                @Override
//                public void accept(DishFlavor dishFlavor) {
//                    dishFlavor.setDishId(id);
//                }
//            });
            //简化
            flavors.forEach(dishFlavor -> dishFlavor.setDishId(id));
            //调用mapper接口，完成口味数据的新增
            dishFlavorMapper.insert(flavors);

        }
    }

    /**
     * 根据id查询菜品
     * 类型 DishVO
     * @param id
     * @return
     */
    @Override
    public DishVO getById(Long id) {
        //还需要拿到categoryName的属性值
        //这里需要查询两张表
       DishVO dishVO=   dishMapper.getById(id);
//        System.out.println(dishVO.getFlavors());// 输出为空 []
        //调用DishFlavorMapper接口，查询该菜品关联的口味
        List<DishFlavor> flavorList = dishFlavorMapper.getById(id);
        dishVO.setFlavors(flavorList);

        return dishVO;
    }

    /**
     * 根据分类id查询菜品
     * 返回的是一个集合
     * @param categoryId
     * @return
     */
    @Override
    public List<Dish> getByType(Long categoryId) {
        return  dishMapper.getByType(categoryId);
    }


    /**
     * 根据id批量删除菜品
     * 只有停售的菜品可以删除
     * 关联的口味也要删除
     * 有套餐关联不能删除
     * @param ids
     */
    @Override
    @Transactional //事务
    public void delete(List<Long> ids) {
        //1.根据主键id查询菜品，判断菜品的起售状态
        List<Dish> dishList = dishMapper.getByids(ids);
        //对返回的集合进行遍历，查看每个菜品的状态
        for (Dish dish : dishList) {
            //起售状态不能删除
           if (dish.getStatus() == StatusConstant.ENABLE){
               throw new DeletionNotAllowedException(MessageConstant.DISH_ON_SALE);
           }
        }

        //2.根据菜品id查询关联的套餐
       Integer count= setmealDishMapper.getByIds(ids);
        if (count > 0 ){
            //当统计出来有关联的套餐，抛出异常
            throw new DeletionNotAllowedException(MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
        }

        //3.删除菜品
        dishMapper.delete(ids);
        //4.删除菜品关联的口味
        dishFlavorMapper.delete(ids);
    }


    /**
     * 修改菜品
     * 更新dish表中数据同时也需要更新dish_flavor表中的数据
     * 在修改口味表中存在问题
     * 如果是添加口味的话是 没有dishid的
     * 对于修改口味，可以先将数据库中该菜品对应的口味删除，在添加口味
     * @param dishDTO
     */
    @Override
    @Transactional
    public void update(DishDTO dishDTO) {
        //更新dish表中数据
        Dish dish=new Dish();
        BeanUtils.copyProperties(dishDTO,dish);
        dishMapper.update(dish);
        //更新dish_flavor表中数据
       /*  ** 存在问题**
       //获得dishDTO对象中flavors属性值
        List<DishFlavor> flavorList = dishDTO.getFlavors();
        //将这个集合中的参数传递过去
        //这个集合可能不止有一个DishFlavor对象
        for (DishFlavor dishFlavor : flavorList) {
            Long dishId = dishFlavor.getDishId();
            String name = dishFlavor.getName();
            String value = dishFlavor.getValue();
            dishFlavorMapper.update(dishId,name,value);
        }*/
        //1.可以先将该菜品对于的口味删除
        List<Long> list=new ArrayList<>();
        list.add(dishDTO.getId());
        dishFlavorMapper.delete(list);
        //2.在菜品的新口味添加到表中
        List<DishFlavor> flavors = dishDTO.getFlavors();
        if (flavors != null && flavors.size() > 0){
            for (DishFlavor flavor : flavors) {
                flavor.setDishId(dish.getId());
            }
            dishFlavorMapper.insert(flavors);
        }

    }

    /**
     * 菜品起售停售
     * 如果菜品停售了，还需要将关联的套餐停售掉
     * @param status
     */
    @Override
    @Transactional
    public void changeStatus(Integer status,Long id) {
       //构建菜品对象
        Dish dish = Dish.builder().id(id).status(status).build();
        //更新菜品数据
        dishMapper.update(dish);

        if (status == StatusConstant.DISABLE){
            //当状态为停售时,需要将关联的套餐也停售

            //1.根据菜品id，查询关联的的套餐
            List<Long> list = setmealDishMapper.getById(id); // list集合表示关联套餐的id
            //2.根据套餐的id去setmeal表中修改数据，修改 status 的属性值
            if (list != null && list.size()> 0 ){
                for (Long setmealId : list) {
                    //根据setmealId，状态为0构建Setmeal对象
                    Setmeal setmeal=Setmeal.builder().id(setmealId).status(StatusConstant.DISABLE).build();
                    setmealMapper.update(setmeal);
                }
            }
        }
    }

    @Override
    public List<DishVO> listWithFlavor(Long categoryId) {
        List<Dish> list = dishMapper.getByType(categoryId);
        List<DishVO> dishVOList=new ArrayList<>();

        for (Dish d : list) {
            //根据菜品的id查询对应的口味
            List<DishFlavor> dishFlavors = dishFlavorMapper.getById(d.getId());
            DishVO dishVO=new DishVO();
            BeanUtils.copyProperties(d,dishVO);
            dishVO.setFlavors(dishFlavors);
            dishVOList.add(dishVO);
        }

        return dishVOList;
    }
}
